Überblick
Begleitendes Beispiel (Ilg / Baumeister 2019).
Datenaufbereitung
Die Daten wurden aus STAT-TAB als csv-Datei exportiert.

Sofort fällt der Peak im Juni 2012 bei Inverkehrssetzungen auf - verursacht durch eine Änderung der CO2-Emissionsvorschriften ab Juli 2012 (https://www.bfs.admin.ch/bfs/de/home/dienstleistungen/fuer-medienschaffende/medienmitteilungen.assetdetail.36344.html).
Für den Zweck der Analyse - eine Prognose der Entwicklung des Automobilmarktes für ein Jahr, ist dieser Ausreißer eher störend. Sinnvoller ist es auf Daten ab 2013 zurückzugreifen. Ein erster Blick auf die Daten mit summary zeigt, dass sich die Inverkehrssetzungen im Intervall von 19.129 bis 35.008 bewegen, im Durchschnitt sind es 26.064 Inverkehrssetzungen. Es werden keine fehlenden Werte angezeigt.
Datum IVS
Min. :2013-01-31 Min. :19129
1st Qu.:2014-07-23 1st Qu.:23105
Median :2016-01-15 Median :26184
Mean :2016-01-14 Mean :26064
3rd Qu.:2017-07-07 3rd Qu.:28502
Max. :2018-12-31 Max. :35008
In der folgenden Abbildung sind die Daten aus dem Berichtsjahr 2018 blau gekennzeichnet, das sie in der Folge nicht zur Schätzung sondern zur Validierung des Modells herangezogen werden, um dessen Prognosefähigkeit beurteilen zu können. Konnte man beim Analysezeitraum 2005 - 2018 noch einen positiven lineare Trend bei Inverkehrssetzungen vermuten, so ist dies in der verkürzten Analyseperiode nicht erkennbar. Die Werte schwanken zudem erheblich, wobei die meisten (90 %) der Werte zwischen 21.700 und 31.400 Inverkehrssetzungen liegen.

Modellierung
Lineares Grundmodell
Zahlreiche Modelle werden in der Zeitreihenanalyse verwendet (vgl. einführend Backhaus et al. (2018), S. 126 ff). Beim linearen Modell erfolgt in der Grundform additive Zerlegung \(Y = A + K + S + u\) mit \(Y\) als zu erklärender Variable, \(A\) als Trendkomponente, \(K\) als Konjunkturkomponente (lange zyklische Komponente), \(S\) als Saisonkomponente und \(u\) als Störgröße oder zufällige Komponente. Im einfachsten Fall ohne Saison- und Konjunkturkomplenten reduziert sich das Modell auf \(Y = A + u\). Mit der Spezifikation der Trendkomponente \(A\) entsteht das lineare Trendmodell: \[Y = \alpha + \beta \cdot t + u\]
Auch zahlreiche nichtlineare Modelle können über geeignete Transformationen im linearen Kontext analysiert werden. Zu nennen sind bspw. das Quadradwurzelmodell \(Y = \alpha + \beta \sqrt t + u\) oder das logarithmische Modell \(Y = \alpha + \beta \cdot \ln (t) + u\) , die beide Sättigungseffekte abbilden können. Für einen Überblick über weitere Modelle und geeignete Linearisierungen vgl. Backhaus et al. (2018), S 148 ff.
Ein Trend und eine Konjunkturkomponente sind aus der Abbildung nicht zu erwarten, die zyklische Schwankung ist jedoch deutlich. Für die Modellbildung werden nur die Daten von 2013 bis 2017 verwendet, 2018 wird für die Beurteilung der Modellperformance zurückgehalten.
Zur Modellierung der Monate werden die Monatsbezeichnungen in zweistellige Zeichenketten transformiert (“01” bis “12”). R erzeugt daraus automatisch 11 Dummyvariablen zur Abbildung der Monate im Modell.
Call:
lm(formula = IVS ~ Datum + Monat, data = ivs_simple_train)
Residuals:
Min 1Q Median 3Q Max
-2676.5 -1014.5 170.3 724.4 3164.6
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.120e+04 6.427e+03 1.742 0.08801 .
Datum 5.702e-01 3.880e-01 1.469 0.14839
Monat02 2.311e+03 9.821e+02 2.353 0.02284 *
Monat03 9.143e+03 9.823e+02 9.308 3.08e-12 ***
Monat04 7.511e+03 9.827e+02 7.644 8.71e-10 ***
Monat05 6.552e+03 9.832e+02 6.664 2.64e-08 ***
Monat06 1.018e+04 9.838e+02 10.345 1.06e-13 ***
Monat07 6.321e+03 9.846e+02 6.420 6.22e-08 ***
Monat08 1.228e+03 9.855e+02 1.246 0.21899
Monat09 3.193e+03 9.866e+02 3.236 0.00222 **
Monat10 4.528e+03 9.878e+02 4.584 3.38e-05 ***
Monat11 4.778e+03 9.891e+02 4.831 1.49e-05 ***
Monat12 1.123e+04 9.906e+02 11.337 4.79e-15 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 1553 on 47 degrees of freedom
Multiple R-squared: 0.862, Adjusted R-squared: 0.8267
F-statistic: 24.46 on 12 and 47 DF, p-value: 3.282e-16
Der Anteil der erklärten Varianz beträgt über 86 Prozent. Die meisten der Saision-Dummies haben statistisch signifikante Koeffizienten, gleiches gilt für das Modell im Gesamten (vgl. F-Statistik).
Prüfung der Modellierungsvoraussetzungen
Wir prüfen die Modellierungsvoraussetzungen analog zu Backhaus et al. (2018), S. 98 ff).
Nichtlinearität: die graphische Darstellung lässt - unter Berücksichtigung der Saisonkomponente vermuten, dass kein nennenswerter linearer Trend besteht.
Erwartungswert der Störgröße = 0: ist nicht von Bedeuutung, wirkt sich ggf. auf den Koeffizienten b0 aus.
Falsche Regressorenauswahl: Multikollinearität falsch spezifizierter Regressoren verzerrt die Parmeterschätzer, bei fehlender Multikollinearität wirken sie sich zumindest wieder auf den Ordinatenabschnitt b0 aus. Mit \(Datum\) und \(Monat\) sind hier allerdings keine überflüssigen Regressoren erkennbar.
Heteroskedastizität: Der Plot der Residuen gegen die erklärte Variable lässt keine für Heteroskedastizität typischen Verläufe erkennen.

Heteroskedastizität kann auch mit dem Goldfeld-Quandt-Test überprüft werden. Die Nullhypothese (Homoskedastizität) kann nicht verworfen werden.
Goldfeld-Quandt test
data: mod
GQ = 0.85735, df1 = 17, df2 = 17, p-value = 0.6227
alternative hypothesis: variance increases from segment 1 to 2
- Autokorrelation: Inbesondere bei Zeitreihen besteht die Gefahr der Verzerrung des Standardfehlers der Regressionskoeffizienten durch autokorrelierte Residuen. Im Ergebnis ergeben sich dann verzerrte Konfidenzintervalle für die Regressionskoeffizienten. Eine visuelle Prüfung erfolgt wie bei der Heterskedastizität im Plot der Residuen gegen die geschätzen Werte. Ebenso ist die Prüfung mit Durbin-Watson-Test möglich, dessen Nullhypothese (keine Autokorrelation) nicht verworfen werden kann.
Durbin-Watson test
data: mod
DW = 1.9995, p-value = 0.4883
alternative hypothesis: true autocorrelation is greater than 0
- Multikollinearität: Schätzungen für Regressionskoeffizienten werden unzuverlässiger, wenn sich die Koeffizenten aus anderen Modellkoeffizienten errechnen lassen. Paarweise Multikollinearität ist vorhanden, wenn der Betrag der paarweisen Korrelationen nahe 1 ist. Abhängigkeiten von mehreren anderen Variablen kann durch die Toleranz oder deren Kehrwert, den Varianz-Inflation-Factor (VIF) ermittelt werden. VIF-Werte im bereich von 10 oder größer sind auf jeden Fall problematisch. Im Beispiel ist die Multikollinearität mit Datum bzw. Monat als Regressoren nicht relevant.

GVIF Df GVIF^(1/(2*Df))
Datum 1.041522 1 1.020550
Monat 1.041522 11 1.001851
- Normalverteilung der Residuen: Bei großer Stichprobe ist eine Abweichung von der Normalverteilungsannahme nicht so tragisch. De QQ-Plot sieht allerdings nicht perfekt aus.

Erstellung von Prognosen
Das berechnete Modell erlaubt die Berechnung von Prognosewerten. Durch den Vergleich der Prognosewerte für die Testdaten mit den Ist-Werten der Testdaten (2018) können Performance-Maße berechnet werden, die den Vergleich unterschiedlicher Modelle erlauben.

Aus den Regressionskoeffizienten lässt sich eine Saisionfigur ableiten. Dies gilt ähnlich, wenn man Box-Plots der monatlich gruppierten Daten erstellt.

Alternative Modellierung über Quartale?
Die Modellierung der einzelnen Monate im Modell impliziert neben dem Datum weitere 11 Dummyvariablen. Es stellt sich die Frage, ob es nicht ein einfacheres Modell gibt. Ein Ansatzpunkt wäre statt Monaten Dummyvariablen für Quartale zu verwenden.
Call:
lm(formula = IVS ~ Datum + Quartal, data = ivs_simple_train)
Residuals:
Min 1Q Median 3Q Max
-6401 -2848 -539 3056 7698
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 1.330e+04 1.532e+04 0.868 0.389
Datum 7.127e-01 9.312e-01 0.765 0.447
Quartal 4.451e+02 4.391e+02 1.014 0.315
Residual standard error: 3730 on 57 degrees of freedom
Multiple R-squared: 0.03372, Adjusted R-squared: -0.0001797
F-statistic: 0.9947 on 2 and 57 DF, p-value: 0.3762
Der Erklärungsgehalt ist jedoch vernachlässigbar, das Saisonverhalten der IVS ist nicht über Quartale abbildbar, nur 3 % der Varianz werden über ein Quartalmodell erklärt, das Modell ist zudem nicht statistsich signifikant.
Test einer alternative Modellierung als ARIMA
Ein Alternative könnte die Betrachtung des Umsätze als ARIMA-Prozess sein. ARIMA steht für Autoregressive Intergrierte Moving Average - Prozesse. Dabei handelt es sich um zusammengesetzte Prozessmodelle. der autoregressive Teil bezieht nimmt Bezug auf die Realisiationen der Vorperioden. Der Moving-Average-Teil bilden den gewogenen Durchschnitt der Fehler der vergangenen Perioden. Sind die Prozesse zudem nicht stationär (xxx), werden diese zunächst ein- oder mehrmals differenziert, wodurch Stationarität erreichbar ist. Durch Integration der Stationären Prozesse kann man wieder auf den ursprünglichen Prozess zurückschließen.
Umwandlung der Daten in eine Zeitreihe (Klasse ts) und Darstellung von Linienplot, ACF und PACF (Autocorrelationfunction und partial ACF).

Die Reihe ist nicht stationär. Erst die zweifache Differenzierung bringt ein Ergebnis:


Ljung-Box test
data: Residuals from ARIMA(2,1,0)(0,1,1)[12]
Q* = 15.892, df = 9, p-value = 0.06917
Model df: 3. Total lags used: 12


Im Ergebnis erhalten wir ein erheblich besseres Modell. rmse gesunken von 2.522 auf 1890.
Differenzierung der Antriebsart
Die Wiederholung der Analyse mit dem zusätzlichen Regressor zeigt ein völlig anderes Bild.


Die Treibstoffarten “Anderer” und “Ohne Motor” spielen in der Analyse keine besondere Rolle. Zur besseren Übersichtlichkeit werden sie ausgeschlossen.


Lineare Modelle je Treibstoffart
Modelle berechnen und plotten

ARIMA-Modelle je Treibstoffart
Modelle berechnen und plotten
[[1]]
Fehler in as.Date.numeric(value) : 'origin' muss angegeben werden

Quellen
Backhaus et al. (2018): Multivariate Analysemethoden. Eine anwendungsorientierte Einführung. 15 Aufl. Berlin. Heidelberg. Springer-Verlag.
Ilg, Markus; Baumeister, Alexander (2019): Analytics im Marketing-Controlling. In: Die Digitalisierung des Controllings: Anwendungsbeispiele aus Theorie und Praxis, hrsg. von Imke Keimer und Ulrich Egle. Springer.
Ruppert, David; Matteson, David S. (2015): Statistics and Data Analysis for Financial Engineering Springer-Verlag
LS0tCnRpdGxlOiAiSW52ZXJrZWhyc3NldHp1bmdlbiBpbiBkZXIgU2Nod2VpeiIKb3V0cHV0OiBodG1sX25vdGVib29rCmF1dGhvcjogCi0gbmFtZSAgIDogIk1hcmt1cyBJbGciCiAgZW1haWwgOiAibWFya3VzLmlsZ0BtYXJrdXMtaWxnLmF0IgoKLS0tCgojIyMgw5xiZXJibGljawoKQmVnbGVpdGVuZGVzIEJlaXNwaWVsIChJbGcgLyBCYXVtZWlzdGVyIDIwMTkpLgoKYGBge3Igc2V0dXAsIGluY2x1ZGU9RkFMU0V9CiMgSW5pdGlhbGlzZXJ1bmcgZGVzIE5vdGVib29rcwprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IEZBTFNFKQoKIyBCZW7DtnRpZ3RlIEJpYmxpb3RoZWtuIGxhZGVuCmxpYnJhcnkodGlkeXZlcnNlKSAgIyByZWFkciwgZHBseXIsIC4uLiAKbGlicmFyeShsdWJyaWRhdGUpICAjIERhdHVtIHVuZCBVaHJ6ZWl0CmxpYnJhcnkobW9kZWxyKSAgICAgIyBNb2RlbGxpZXJ1bmcKbGlicmFyeShicm9vbSkgICAgICAjIFp1c2FtbWVuZmFzc3VuZyB2b24gTW9kZWxsZXJnZWJuaXNzZW4gaW4gRGF0YWZyYW1lcwpsaWJyYXJ5KGNvcnJwbG90KSAgICMgWnVzYW1tZW5mYXNzdW5nIHZvbiBNb2RlbGxlcmdlYm5pc3NlbiBpbiBEYXRhZnJhbWVzCiAKbGlicmFyeShsbXRlc3QpICAgICAjIGbDvHIgR29sZGZlbGR0L1F1YW5kdC1UZXN0CmxpYnJhcnkoY2FyKSAgICAgICAgIyBmw7xyIFZJRgoKbGlicmFyeShmb3JlY2FzdCkgICAjIGbDvHIgekIgZ2d0c2Rpc3BsYXkuCmxpYnJhcnkoYXN0c2EpICAgICAgIyBmw7xyIHNhcmltYSwgc2FyaW1hLmZvcgpsaWJyYXJ5KGNvd3Bsb3QpICAgICMgYXJyYW5nZSBtdWx0aXBsZSBwbG90cwoKdGhlbWVfc2V0KHRoZW1lX2J3KCkpICMgQWJiaWxkdW5nZW4gaW0gRHJ1Y2sgYmVzc2VyIGxlc2JhciBhbHMgbWl0IGRlbSBEZWZhdWx0LVRoZW1lIHRoZW1lX2dyYXkoKQoKIyBCZXJlY2huZSBkZW4gbGV0enRlbiBUYWcgZGVzIE1vbmF0cwptb250aHNFbmQgPC0gZnVuY3Rpb24oSmFociwgTW9uYXQpIHsKICByZXF1aXJlKGx1YnJpZGF0ZSkKICBwYXN0ZShKYWhyLCBNb25hdCwgIjAxIiwgc2VwID0gIi0iKSAlPiUgeW1kKCkgJT4lIGNlaWxpbmdfZGF0ZSh1bml0ID0gIm1vbnRocyIpIC0gMQp9CgojIEZvcm1hdGllcmUgIjEuMjM0LDU2IiBzdGF0dCAiMSwyMzQuNTYiCmZvcm1hdFQgPC0gZnVuY3Rpb24obikgewogIGZvcm1hdChuLCBiaWcubWFyayA9ICIuIiwgZGVjaW1hbC5tYXJrID0gIiwiKQp9CgojIFBlcmZvcm1hbmNlLU1ldHJpa2VuCmZQZXJmb3JtYW5jZSA8LSBmdW5jdGlvbihkYXRhKSB7CiAgYWN0dWFsIDwtIGRhdGEkSVZTCiAgcHJlZGljdGVkIDwtIGRhdGEkcHJlZAogIGxpc3QobWFlID0gTWV0cmljczo6bWFlKGFjdHVhbCwgcHJlZGljdGVkKSwKICAgIG1hcGUgPSBNZXRyaWNzOjptYXBlKGFjdHVhbCwgcHJlZGljdGVkKSwKICAgIG1zZSA9IE1ldHJpY3M6Om1zZShhY3R1YWwsIHByZWRpY3RlZCksCiAgICBybXNlID0gTWV0cmljczo6cm1zZShhY3R1YWwsIHByZWRpY3RlZCkpICU+JSAKICAgIGJpbmRfcm93cygpCn0KCmBgYAoKIyMjIERhdGVuaGVya3VuZnQKU2Nod2VpemVyaXNjaGUgRWlkZ2Vub3NzZW5zY2hhZnQgLSBCdW5kZXNhbXQgZsO8ciBTdGF0aXN0aWsuICAKQWJnZXJ1ZmVuIGF1cyBTVEFULVRBQiBhbSAyNC44LjIwMTk6ICAKaHR0cHM6Ly93d3cucHh3ZWIuYmZzLmFkbWluLmNoL3B4d2ViL2RlL3B4LXgtMTEwMzAyMDIwMF8xMjAvLS9weC14LTExMDMwMjAyMDBfMTIwLnB4CgojIyMgRGF0ZW5hdWZiZXJlaXR1bmcKCkRpZSBEYXRlbiB3dXJkZW4gYXVzIFNUQVQtVEFCIGFscyBjc3YtRGF0ZWkgZXhwb3J0aWVydC4KCmBgYHtyIG1lc3NhZ2U9RkFMU0V9CgojIGNzdiBhbHMgUm9oZGF0ZW4gaW1wb3J0aWVyZW4KaXZzX3JhdyA8LQogIHJlYWRfY3N2KGZpbGUgPSAiRGF0ZW4vMjAxOTA4MjQgTmV1enVsYXNzdW5nZW4gQ0guY3N2IiwKICAgICAgICAgICBza2lwID0gMiwKICAgICAgICAgICBsb2NhbGUgPSBsb2NhbGUoZW5jb2RpbmcgPSAibGF0aW4xIikpICMgV2luZG93cyBMYXRpbiAxCgojIEJlc2NocsOkbmt1bmcgYXVmIHJlbGV2YW50ZSBEYXRlbgppdnNfc2ltcGxlIDwtIGl2c19yYXcgJT4lCiAgc2VsZWN0KC0iRmFocnpldWdncnVwcGUgLyAtYXJ0IikgJT4lICMgU3BhbHRlIEZhaHJ6ZXVncnVwcGUgbMO2c2NoZW4KICBnYXRoZXIoa2V5ID0gSmFociwgdmFsdWUgPSAiSVZTIiwgLU1vbmF0KSAlPiUgIyBkaWUgSmFocmVzc3BhbHRlbiBpbiBaZWlsZW4gdW1iYXVlbgogIG11dGF0ZShEYXR1bSA9IG1vbnRoc0VuZChKYWhyLCBNb25hdCkpICU+JSAgIyBKYWhyIE1vbmF0IHVtYmF1ZW4gYXVmIGVpbmUgRGF0dW0genVtIE1vbmF0c2VuZGUKICBzZWxlY3QoRGF0dW0sIElWUykgIyBudXIgZGllIFNwYWx0ZW4gRGF0dW0gdW5kIElWUyBhdXN3w6RobGVuCgojIERhcnN0ZWxsdW5nIGRlciBtb25hdGxpY2hlbiBJbnZlcmtlaHJzc2V0enVuZ2VuIGFscyBTY2F0dGVycGxvdAppdnNfc2ltcGxlICU+JQogIGdncGxvdChhZXMoeCA9IERhdHVtKSkgKwogIHNjYWxlX3hfZGF0ZSggIyBGb3JtYXRpZXJ1bmdzYW53ZWlzdW5nZW4gZsO8ciBkaWUgeC1BY2hzZQogICAgbmFtZSA9ICIiLAogICAgZGF0ZV9sYWJlbHMgPSAiJW0vJXkiLAogICAgZGF0ZV9taW5vcl9icmVha3MgPSAiMiBtb250aHMiLAogICAgZGF0ZV9icmVha3MgPSAieWVhcnMiCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCAjIEZvcm1hdGllcnVuZ3NhbndlaXN1bmdlbiBmw7xyIGRpZSB5LUFjaHNlCiAgICBuYW1lID0gIkludmVya2VocnNzZXR6dW5nZW4gcHJvIE1vbmF0IiwKICAgIGxpbWl0cyA9IGMoMCwgNDUwMDApLAogICAgbGFiZWxzID0gZm9ybWF0VCAjIEFuemVpZ2UgZGVyIFNrYWxhIG1pdCBUYXVzZW5kZXItUHVua3QKICApICsKICBnZW9tX3BvaW50KGFlcygKICAgIHkgPSBJVlMsICMgSVZTIGF1ZiBkZXIgeS1BY2hzZQogICAgc2hhcGUgPSAoSVZTID4gNDAwMDApLCAjIGVpZ2VuZSBGb3JtIGbDvHIgV2VydGUgw7xiZXIgNDAwMDAKICAgIGNvbG9yID0gKElWUyA+IDQwMDAwKSAgIyBlaWdlbmUgRmFyYmUgZsO8ciBXZXJ0ZSDDvGJlciA0MDAwMAogICkpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIiwgInJlZCIpKSArICMgbWFudWVsbGUgRmFyYnNrYWxhCiAgZ3VpZGVzKGNvbG9yID0gIm5vbmUiKSArICMgS2VpbmUgTGVnZW5kZSBmw7xyIGRpZSBGYXJiZQogIGd1aWRlcyhzaGFwZSA9ICJub25lIikgKyAjIEtlaW5lIExlZ2VuZGUgZsO8ciBkaWUgRmFyYmUKICBsYWJzKHRpdGxlID0gIm1vbmF0bGljaGUgSW52ZXJrZWhyc3NldHp1bmdlbiB2b24gUGVyc29uZW5rcmFmdHdhZ2VuIiwKICAgICAgIHN1YnRpdGxlID0gIlNjaHdlaXosIDIwMDUgLSAyMDE4IikKCmBgYAoKU29mb3J0IGbDpGxsdCBkZXIgUGVhayBpbSBKdW5pIDIwMTIgYmVpIEludmVya2VocnNzZXR6dW5nZW4gYXVmIC0gdmVydXJzYWNodCBkdXJjaCBlaW5lIMOEbmRlcnVuZyBkZXIgQ08yLUVtaXNzaW9uc3ZvcnNjaHJpZnRlbiBhYiBKdWxpIDIwMTIgKGh0dHBzOi8vd3d3LmJmcy5hZG1pbi5jaC9iZnMvZGUvaG9tZS9kaWVuc3RsZWlzdHVuZ2VuL2Z1ZXItbWVkaWVuc2NoYWZmZW5kZS9tZWRpZW5taXR0ZWlsdW5nZW4uYXNzZXRkZXRhaWwuMzYzNDQuaHRtbCkuICAKCkbDvHIgZGVuIFp3ZWNrIGRlciBBbmFseXNlIC0gZWluZSBQcm9nbm9zZSBkZXIgRW50d2lja2x1bmcgZGVzIEF1dG9tb2JpbG1hcmt0ZXMgZsO8ciBlaW4gSmFociwgaXN0IGRpZXNlciBBdXNyZWnDn2VyIGVoZXIgc3TDtnJlbmQuIFNpbm52b2xsZXIgaXN0IGVzIGF1ZiBEYXRlbiBhYiAyMDEzIHp1csO8Y2t6dWdyZWlmZW4uIEVpbiBlcnN0ZXIgQmxpY2sgYXVmIGRpZSBEYXRlbiBtaXQgYHN1bW1hcnlgIHplaWd0LCBkYXNzIHNpY2ggZGllIEludmVya2VocnNzZXR6dW5nZW4gaW0gSW50ZXJ2YWxsIHZvbiBgciBmb3JtYXRUKG1pbihpdnNfc2ltcGxlJElWUykpYCBiaXMgYHIgZm9ybWF0VChtYXgoaXZzX3NpbXBsZSRJVlMpKWAgYmV3ZWdlbiwgaW0gRHVyY2hzY2huaXR0IHNpbmQgZXMgYHIgZm9ybWF0VChyb3VuZChtZWFuKGl2c19zaW1wbGUkSVZTKSwwKSlgIEludmVya2VocnNzZXR6dW5nZW4uIEVzIHdlcmRlbiBrZWluZSBmZWhsZW5kZW4gV2VydGUgYW5nZXplaWd0LgoKYGBge3J9Cml2c19zaW1wbGUgPC0gaXZzX3NpbXBsZSAlPiUgZmlsdGVyKERhdHVtID4geW1kKCIyMDEyLTEyLTMxIikpCnN1bW1hcnkoaXZzX3NpbXBsZSkKCmBgYAoKSW4gZGVyIGZvbGdlbmRlbiBBYmJpbGR1bmcgc2luZCBkaWUgRGF0ZW4gYXVzIGRlbSBCZXJpY2h0c2phaHIgMjAxOCBibGF1IGdla2VubnplaWNobmV0LCBkYXMgc2llIGluIGRlciBGb2xnZSBuaWNodCB6dXIgU2Now6R0enVuZyBzb25kZXJuIHp1ciBWYWxpZGllcnVuZyBkZXMgTW9kZWxscyBoZXJhbmdlem9nZW4gd2VyZGVuLCB1bSBkZXNzZW4gUHJvZ25vc2Vmw6RoaWdrZWl0IGJldXJ0ZWlsZW4genUga8O2bm5lbi4gS29ubnRlIG1hbiBiZWltIEFuYWx5c2V6ZWl0cmF1bSAyMDA1IC0gMjAxOCBub2NoIGVpbmVuIHBvc2l0aXZlbiBsaW5lYXJlIFRyZW5kIGJlaSBJbnZlcmtlaHJzc2V0enVuZ2VuIHZlcm11dGVuLCBzbyBpc3QgZGllcyBpbiBkZXIgdmVya8O8cnp0ZW4gQW5hbHlzZXBlcmlvZGUgbmljaHQgZXJrZW5uYmFyLiBEaWUgV2VydGUgc2Nod2Fua2VuIHp1ZGVtIGVyaGVibGljaCwgd29iZWkgZGllIG1laXN0ZW4gKDkwICUpIGRlciBXZXJ0ZSB6d2lzY2hlbiBgciBmb3JtYXRUKHJvdW5kKHF1YW50aWxlKGl2c19zaW1wbGUkSVZTLCAwLjEwKSwgLTIpKWAgdW5kIGByIGZvcm1hdFQocm91bmQocXVhbnRpbGUoaXZzX3NpbXBsZSRJVlMsIDAuOTApLCAtMikpYCBJbnZlcmtlaHJzc2V0enVuZ2VuIGxpZWdlbi4KCmBgYHtyfQpwIDwtIGl2c19zaW1wbGUgJT4lICMgRGlhZ3JhbW1ncnVuZGRhdGVuIGZlc3RsZWdlbgogIGdncGxvdChhZXMoeCA9IERhdHVtKSkgKyAjIERhdHVtc3dlcnRlIGF1ZiBkZXIgeC1BY2hzZQogIHNjYWxlX3hfZGF0ZSgKICAgICMgRm9ybWF0aWVydW5nIGRlciB4LUFjaHNlCiAgICBuYW1lID0gIiIsCiAgICBsaW1pdHMgPSBjKHltZCgiMjAxMy0wMS0wMSIsICIyMDE4LTEyLTMxIikpLAogICAgZGF0ZV9sYWJlbHMgPSAiJVkiLAogICAgZGF0ZV9taW5vcl9icmVha3MgPSAiMiBtb250aHMiLAogICAgZGF0ZV9icmVha3MgPSAieWVhcnMiCiAgKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCAjIEZvcm1hdGllcnVuZyBkZXIgeS1BY2hzZQogICAgbmFtZSA9ICJJbnZlcmtlaHJzc2V0enVuZ2VuIHBybyBNb25hdCIsCiAgICBsaW1pdHMgPSBjKDAsIDQ1MDAwKSwKICAgIGxhYmVscyA9IGZvcm1hdFQpICsKICBzY2FsZV9jb2xvdXJfbWFudWFsKHZhbHVlcyA9IGMoImJsYWNrIiwgImJsdWUiKSkgKyAjIGVpZ2VuZSBGYXJic2thbGEKICBndWlkZXMoY29sb3IgPSAibm9uZSIpICsgIyBrZWluZSBMZWdlbmRlIGbDvHIgZGllIEZhcmJlCiAgbGFicyh0aXRsZSA9ICJtb25hdGxpY2hlIEludmVya2VocnNzZXR6dW5nZW4gdm9uIFBlcnNvbmVua3JhZnR3YWdlbiIsCiAgICAgICBzdWJ0aXRsZSA9ICJTY2h3ZWl6LCAyMDEzIC0gMjAxOCIpCgpwICsgIyBQdW5rdGUgw7xiZXIgZGFzIERpYWdyYW1tIGxlZ2VuCiAgZ2VvbV9saW5lKGFlcyh5ID0gSVZTLAogICAgICAgICAgICAgICAgIGNvbG9yID0gKHllYXIoRGF0dW0pID09IDIwMTgpKSkKCmBgYAoKIyMjIE1vZGVsbGllcnVuZwojIyMjIExpbmVhcmVzIEdydW5kbW9kZWxsCgpaYWhscmVpY2hlIE1vZGVsbGUgd2VyZGVuIGluIGRlciBaZWl0cmVpaGVuYW5hbHlzZSB2ZXJ3ZW5kZXQgKHZnbC4gZWluZsO8aHJlbmQgW0JhY2toYXVzIGV0IGFsLiAoMjAxOCldKGh0dHBzOi8vd3d3LnNwcmluZ2VyLmNvbS9kZS9ib29rLzk3ODM2NjI1NjY1NDEpLCBTLiAxMjYgZmYpLiBCZWltICpsaW5lYXJlbiBNb2RlbGwqIGVyZm9sZ3QgaW4gZGVyIEdydW5kZm9ybSBhZGRpdGl2ZSBaZXJsZWd1bmcgJFkgPSBBICsgSyArIFMgKyB1JCBtaXQgJFkkIGFscyB6dSBlcmtsw6RyZW5kZXIgVmFyaWFibGUsICRBJCBhbHMgVHJlbmRrb21wb25lbnRlLCAkSyQgYWxzIEtvbmp1bmt0dXJrb21wb25lbnRlIChsYW5nZSB6eWtsaXNjaGUgS29tcG9uZW50ZSksICRTJCBhbHMgU2Fpc29ua29tcG9uZW50ZSB1bmQgJHUkIGFscyBTdMO2cmdyw7bDn2Ugb2RlciB6dWbDpGxsaWdlIEtvbXBvbmVudGUuIEltIGVpbmZhY2hzdGVuIEZhbGwgb2huZSBTYWlzb24tIHVuZCBLb25qdW5rdHVya29tcGxlbnRlbiByZWR1emllcnQgc2ljaCBkYXMgTW9kZWxsIGF1ZiAkWSA9IEEgKyB1JC4gTWl0IGRlciBTcGV6aWZpa2F0aW9uIGRlciBUcmVuZGtvbXBvbmVudGUgJEEkIGVudHN0ZWh0IGRhcyBsaW5lYXJlIFRyZW5kbW9kZWxsOiAkJFkgPSBcYWxwaGEgKyBcYmV0YSBcY2RvdCB0ICsgdSQkCgpBdWNoIHphaGxyZWljaGUgbmljaHRsaW5lYXJlIE1vZGVsbGUga8O2bm5lbiDDvGJlciBnZWVpZ25ldGUgVHJhbnNmb3JtYXRpb25lbiBpbSBsaW5lYXJlbiBLb250ZXh0IGFuYWx5c2llcnQgd2VyZGVuLiBadSBuZW5uZW4gc2luZCBic3B3LiBkYXMgUXVhZHJhZHd1cnplbG1vZGVsbCAkWSA9IFxhbHBoYSArIFxiZXRhIFxzcXJ0IHQgKyB1JCBvZGVyIGRhcyBsb2dhcml0aG1pc2NoZSBNb2RlbGwgJFkgPSBcYWxwaGEgKyBcYmV0YSBcY2RvdCBcbG4gKHQpICsgdSQgLCBkaWUgYmVpZGUgU8OkdHRpZ3VuZ3NlZmZla3RlIGFiYmlsZGVuIGvDtm5uZW4uIEbDvHIgZWluZW4gw5xiZXJibGljayDDvGJlciB3ZWl0ZXJlIE1vZGVsbGUgdW5kIGdlZWlnbmV0ZSBMaW5lYXJpc2llcnVuZ2VuIHZnbC4gW0JhY2toYXVzIGV0IGFsLiAoMjAxOCldKGh0dHBzOi8vd3d3LnNwcmluZ2VyLmNvbS9kZS9ib29rLzk3ODM2NjI1NjY1NDEpLCBTIDE0OCBmZi4KCkVpbiBUcmVuZCB1bmQgZWluZSBLb25qdW5rdHVya29tcG9uZW50ZSBzaW5kIGF1cyBkZXIgQWJiaWxkdW5nIG5pY2h0IHp1IGVyd2FydGVuLCBkaWUgenlrbGlzY2hlIFNjaHdhbmt1bmcgaXN0IGplZG9jaCBkZXV0bGljaC4gRsO8ciBkaWUgTW9kZWxsYmlsZHVuZyB3ZXJkZW4gbnVyIGRpZSBEYXRlbiB2b24gMjAxMyBiaXMgMjAxNyB2ZXJ3ZW5kZXQsIDIwMTggd2lyZCBmw7xyIGRpZSBCZXVydGVpbHVuZyBkZXIgTW9kZWxscGVyZm9ybWFuY2UgenVyw7xja2dlaGFsdGVuLgoKWnVyIE1vZGVsbGllcnVuZyBkZXIgTW9uYXRlIHdlcmRlbiBkaWUgTW9uYXRzYmV6ZWljaG51bmdlbiBpbiB6d2Vpc3RlbGxpZ2UgWmVpY2hlbmtldHRlbiB0cmFuc2Zvcm1pZXJ0ICgiMDEiIGJpcyAiMTIiKS4gYFJgIGVyemV1Z3QgZGFyYXVzIGF1dG9tYXRpc2NoIDExIER1bW15dmFyaWFibGVuIHp1ciBBYmJpbGR1bmcgZGVyIE1vbmF0ZSBpbSBNb2RlbGwuIAoKYGBge3J9CgojIERlciBlaW5mYWNoIERhdGFmcmFtZSBpdnNfc2ltcGxlIG1pdCBkZW4gU3BhbHRlbiBJVlMgdW5kIERhdHVtCiMgd2lyIGhpZXIgZXJ3ZWl0ZXJ0OiBkaWUgTnVtbWVyIGRlcyBNb25hdHMgd2lyZCBhbHMgendlaXN0ZWxsaWdlIFplaWNoZW5rZXR0ZSBlcmfDpG56dC4KaXZzX3NpbXBsZSA8LSBpdnNfc2ltcGxlICU+JSAKICBtdXRhdGUoTW9uYXQgPSBzdHJfcGFkKG1vbnRoKERhdHVtKSwgMiwgcGFkID0gIjAiKSkKCiMgQXVmdGVpbGVuIGRlciBEYXRlbiBpbiBlaW4gVHJhaW5pbmdzLSB1bmQgZWluIFRlc3RzZXQKaXZzX3NpbXBsZV90cmFpbiA8LSBpdnNfc2ltcGxlICU+JSBmaWx0ZXIoRGF0dW0gPCBkYXRlKCIyMDE4LTAxLTAxIikpCml2c19zaW1wbGVfdGVzdCA8LSBpdnNfc2ltcGxlICU+JSBmaWx0ZXIoRGF0dW0gPj0gZGF0ZSgiMjAxOC0wMS0wMSIpKQoKIyBFcm5ldXRlIEJlcmVjaG51bmcgZGVzIE1vZGVsbHMgLi4uCm1vZCA8LSBsbShmb3JtdWxhID0gSVZTIH4gRGF0dW0gKyBNb25hdCwgZGF0YSA9IGl2c19zaW1wbGVfdHJhaW4pCgojIC4uLiB1bmQgQXVzZ2FiZSBkZXIgTW9kZWxsZXJnZWJuaXNzZQpzdW1tYXJ5KG1vZCkKCmBgYAoKRGVyIEFudGVpbCBkZXIgZXJrbMOkcnRlbiBWYXJpYW56IGJldHLDpGd0IMO8YmVyIDg2IFByb3plbnQuIERpZSBtZWlzdGVuIGRlciBTYWlzaW9uLUR1bW1pZXMgaGFiZW4gc3RhdGlzdGlzY2ggc2lnbmlmaWthbnRlIEtvZWZmaXppZW50ZW4sIGdsZWljaGVzIGdpbHQgZsO8ciBkYXMgTW9kZWxsIGltIEdlc2FtdGVuICh2Z2wuIEYtU3RhdGlzdGlrKS4KCiMjIyMgUHLDvGZ1bmcgZGVyIE1vZGVsbGllcnVuZ3N2b3JhdXNzZXR6dW5nZW4KV2lyIHByw7xmZW4gZGllIE1vZGVsbGllcnVuZ3N2b3JhdXNzZXR6dW5nZW4gYW5hbG9nIHp1IFtCYWNraGF1cyBldCBhbC4gKDIwMTgpXShodHRwczovL3d3dy5zcHJpbmdlci5jb20vZGUvYm9vay85NzgzNjYyNTY2NTQxKSwgUy4gOTggZmYpLgoKKDEpIE5pY2h0bGluZWFyaXTDpHQ6IGRpZSBncmFwaGlzY2hlIERhcnN0ZWxsdW5nIGzDpHNzdCAtIHVudGVyIEJlcsO8Y2tzaWNodGlndW5nIGRlciBTYWlzb25rb21wb25lbnRlIHZlcm11dGVuLCBkYXNzIGtlaW4gbmVubmVuc3dlcnRlciBsaW5lYXJlciBUcmVuZCBiZXN0ZWh0LgoKKDIpIEVyd2FydHVuZ3N3ZXJ0IGRlciBTdMO2cmdyw7bDn2UgPSAwOiBpc3QgbmljaHQgdm9uIEJlZGV1dXR1bmcsIHdpcmt0IHNpY2ggZ2dmLiBhdWYgZGVuIEtvZWZmaXppZW50ZW4gYjAgYXVzLgoKKDMpIEZhbHNjaGUgUmVncmVzc29yZW5hdXN3YWhsOiBNdWx0aWtvbGxpbmVhcml0w6R0IGZhbHNjaCBzcGV6aWZpemllcnRlciBSZWdyZXNzb3JlbiB2ZXJ6ZXJydCBkaWUgUGFybWV0ZXJzY2jDpHR6ZXIsIGJlaSBmZWhsZW5kZXIgTXVsdGlrb2xsaW5lYXJpdMOkdCB3aXJrZW4gc2llIHNpY2ggenVtaW5kZXN0IHdpZWRlciBhdWYgZGVuIE9yZGluYXRlbmFic2Nobml0dCBiMCBhdXMuIE1pdCAkRGF0dW0kIHVuZCAkTW9uYXQkIHNpbmQgaGllciBhbGxlcmRpbmdzIGtlaW5lIMO8YmVyZmzDvHNzaWdlbiBSZWdyZXNzb3JlbiBlcmtlbm5iYXIuCgooNCkgSGV0ZXJvc2tlZGFzdGl6aXTDpHQ6IERlciBQbG90IGRlciBSZXNpZHVlbiBnZWdlbiBkaWUgZXJrbMOkcnRlIFZhcmlhYmxlIGzDpHNzdCBrZWluZSBmw7xyIEhldGVyb3NrZWRhc3Rpeml0w6R0IHR5cGlzY2hlbiBWZXJsw6R1ZmUgZXJrZW5uZW4uCgpgYGB7cn0KCiMgRGF0YWZyYW1lIHVtIFByb2dub3Nld2VydGUgdW5kIFJlc2lkdWVuIGVyZ8OkbnplbgpkZl9tb2QgPC0gYXVnbWVudChtb2QpCgojU2NhdHRlcnBsb3QgZGVyIFJlc2lkdWVuIGdlZ2VuIGdlc2Now6R0enRlIFdlcnRlCmdncGxvdChkYXRhID0gZGZfbW9kLCBhZXMoeCA9IC5maXR0ZWQsIHkgPSAucmVzaWQpKSArCiAgZ2VvbV9wb2ludCgpCgpgYGAKCkhldGVyb3NrZWRhc3Rpeml0w6R0IGthbm4gYXVjaCBtaXQgZGVtIEdvbGRmZWxkLVF1YW5kdC1UZXN0IMO8YmVycHLDvGZ0IHdlcmRlbi4gRGllIE51bGxoeXBvdGhlc2UgKEhvbW9za2VkYXN0aXppdMOkdCkga2FubiBuaWNodCB2ZXJ3b3JmZW4gd2VyZGVuLgoKYGBge3J9CiMgR29sZGZlbGQtUXVhbmR0LVRlc3QgYXVzIGRlbSBsbXRlc3QtcGFja2FnZS4KZ3F0ZXN0KG1vZCkKCmBgYAoKCig1KSBBdXRva29ycmVsYXRpb246IEluYmVzb25kZXJlIGJlaSBaZWl0cmVpaGVuIGJlc3RlaHQgZGllIEdlZmFociBkZXIgVmVyemVycnVuZyBkZXMgU3RhbmRhcmRmZWhsZXJzIGRlciBSZWdyZXNzaW9uc2tvZWZmaXppZW50ZW4gZHVyY2ggYXV0b2tvcnJlbGllcnRlIFJlc2lkdWVuLiBJbSBFcmdlYm5pcyBlcmdlYmVuIHNpY2ggZGFubiB2ZXJ6ZXJydGUgS29uZmlkZW56aW50ZXJ2YWxsZSBmw7xyIGRpZSBSZWdyZXNzaW9uc2tvZWZmaXppZW50ZW4uIEVpbmUgdmlzdWVsbGUgUHLDvGZ1bmcgZXJmb2xndCB3aWUgYmVpIGRlciBIZXRlcnNrZWRhc3Rpeml0w6R0IGltIFBsb3QgZGVyIFJlc2lkdWVuIGdlZ2VuIGRpZSBnZXNjaMOkdHplbiBXZXJ0ZS4gRWJlbnNvIGlzdCBkaWUgUHLDvGZ1bmcgbWl0IER1cmJpbi1XYXRzb24tVGVzdCBtw7ZnbGljaCwgZGVzc2VuIE51bGxoeXBvdGhlc2UgKGtlaW5lIEF1dG9rb3JyZWxhdGlvbikgbmljaHQgdmVyd29yZmVuIHdlcmRlbiBrYW5uLgoKYGBge3J9CiMgRHVyYmluLVdhdHNvbi1UZXN0IChwYWNrYWdlIGxtdGVzdCkKZHd0ZXN0KG1vZCkKYGBgCgooNikgTXVsdGlrb2xsaW5lYXJpdMOkdDogU2Now6R0enVuZ2VuIGbDvHIgUmVncmVzc2lvbnNrb2VmZml6aWVudGVuIHdlcmRlbiB1bnp1dmVybMOkc3NpZ2VyLCB3ZW5uIHNpY2ggZGllIEtvZWZmaXplbnRlbiBhdXMgYW5kZXJlbiBNb2RlbGxrb2VmZml6aWVudGVuIGVycmVjaG5lbiBsYXNzZW4uIFBhYXJ3ZWlzZSBNdWx0aWtvbGxpbmVhcml0w6R0IGlzdCB2b3JoYW5kZW4sIHdlbm4gZGVyIEJldHJhZyBkZXIgcGFhcndlaXNlbiBLb3JyZWxhdGlvbmVuIG5haGUgMSBpc3QuIEFiaMOkbmdpZ2tlaXRlbiB2b24gbWVocmVyZW4gYW5kZXJlbiBWYXJpYWJsZW4ga2FubiBkdXJjaCBkaWUgVG9sZXJhbnogb2RlciBkZXJlbiBLZWhyd2VydCwgZGVuIFZhcmlhbnotSW5mbGF0aW9uLUZhY3RvciAoVklGKSBlcm1pdHRlbHQgd2VyZGVuLiBWSUYtV2VydGUgaW0gYmVyZWljaCB2b24gMTAgb2RlciBncsO2w59lciBzaW5kIGF1ZiBqZWRlbiBGYWxsIHByb2JsZW1hdGlzY2guIEltIEJlaXNwaWVsIGlzdCBkaWUgTXVsdGlrb2xsaW5lYXJpdMOkdCBtaXQgRGF0dW0gYnp3LiBNb25hdCBhbHMgUmVncmVzc29yZW4gbmljaHQgcmVsZXZhbnQuCgpgYGB7cn0KIyBBbGxlIFNwYWx0ZW4gaW4gbnVtZXJpc2NoZSBXZXJ0ZSB1bXdhbmRlbG4KbSA8LSBpdnNfc2ltcGxlX3RyYWluWywtM10gJT4lCiAgbXV0YXRlKERhdHVtID0gYXMubnVtZXJpYyhEYXR1bSkpCgojIEtvcnJlbGF0aW9uc21hdHJpeCBiZXJlY2huZW4gdW5kIHZpc3VhbGlzaWVyZW4KY29ycnBsb3QoY29yciA9IGNvcihtKSwgbWV0aG9kID0gInBpZSIpCgojIFZhcmlhbnotSW5mbGF0aW9uLUZha3RvcmVuIGJlcmVjaG5lbgp2aWYobW9kKQpgYGAKCig3KSBOb3JtYWx2ZXJ0ZWlsdW5nIGRlciBSZXNpZHVlbjogQmVpIGdyb8OfZXIgU3RpY2hwcm9iZSBpc3QgZWluZSBBYndlaWNodW5nIHZvbiBkZXIgTm9ybWFsdmVydGVpbHVuZ3Nhbm5haG1lIG5pY2h0IHNvIHRyYWdpc2NoLiBEZSBRUS1QbG90IHNpZWh0IGFsbGVyZGluZ3MgbmljaHQgcGVyZmVrdCBhdXMuCgpgYGB7cn0KcXFub3JtKGRmX21vZCQucmVzaWQpCnFxbGluZShkZl9tb2QkLnJlc2lkLCBkYXRheCA9IEZBTFNFLCBkaXN0cmlidXRpb24gPSBxbm9ybSwKICAgICAgIHByb2JzID0gYygwLjI1LCAwLjc1KSwgcXR5cGUgPSA3KQoKYGBgCgojIyMgRXJzdGVsbHVuZyB2b24gUHJvZ25vc2VuCgpEYXMgYmVyZWNobmV0ZSBNb2RlbGwgZXJsYXVidCBkaWUgQmVyZWNobnVuZyB2b24gUHJvZ25vc2V3ZXJ0ZW4uIER1cmNoIGRlbiBWZXJnbGVpY2ggZGVyIFByb2dub3Nld2VydGUgZsO8ciBkaWUgVGVzdGRhdGVuIG1pdCBkZW4gSXN0LVdlcnRlbiBkZXIgVGVzdGRhdGVuICgyMDE4KSBrw7ZubmVuIFBlcmZvcm1hbmNlLU1hw59lIGJlcmVjaG5ldCB3ZXJkZW4sIGRpZSBkZW4gVmVyZ2xlaWNoIHVudGVyc2NoaWVkbGljaGVyIE1vZGVsbGUgZXJsYXViZW4uCgpgYGB7cn0KCiMgUHJvZ25vc2V3ZXJ0ZSBhdWZncnVuZCBkZXMgYmVyZWNobmV0ZW4gTW9kZWxscyBlcmfDpG56ZW4KaXZzX3NpbXBsZV9wcmVkIDwtIGl2c19zaW1wbGVfdGVzdCAlPiUgYWRkX3ByZWRpY3Rpb25zKG1vZGVsID0gbW9kKQoKIyBHcmFmaXNjaGUgRGFyc3RlbGx1bmcgZGVyIFByb2dub3NlbiAoZ2VzdHJpY2hlbHQpCnAgKyBnZW9tX2xpbmUoYWVzKHkgPSBJVlMsIGNvbG9yID0gKHllYXIoRGF0dW0pID09IDIwMTgpKSkgKwogIGdlb21fbGluZShhZXMoeSA9IHByZWQpLAogICAgICAgICAgICBsaW5ldHlwZSA9IDIsICMgZGFzaGVkCiAgICAgICAgICAgIGNvbG9yID0gInJlZCIsCiAgICAgICAgICAgIGRhdGEgPSBpdnNfc2ltcGxlX3ByZWQpCgojIFBlcmZvcm1hbmNlLUJlcmVjaG51bmcgYXVmIGRlciBCYXNpcyBkZXIgVGVzdGRhdGVuCmZQZXJmb3JtYW5jZShkYXRhLmZyYW1lKElWUyA9IGl2c19zaW1wbGVfcHJlZCRJVlMsIHByZWQgPSBpdnNfc2ltcGxlX3ByZWQkcHJlZCkpCgpgYGAKCkF1cyBkZW4gUmVncmVzc2lvbnNrb2VmZml6aWVudGVuIGzDpHNzdCBzaWNoIGVpbmUgU2Fpc2lvbmZpZ3VyIGFibGVpdGVuLiBEaWVzIGdpbHQgw6RobmxpY2gsIHdlbm4gbWFuIEJveC1QbG90cyBkZXIgbW9uYXRsaWNoIGdydXBwaWVydGVuIERhdGVuIGVyc3RlbGx0LgoKYGBge3J9CgpnZ3Bsb3QoaXZzX3NpbXBsZV90cmFpbiAlPiUgYWRkX3ByZWRpY3Rpb25zKG1vZGVsID0gbW9kKSwgYWVzKHggPSBNb25hdCkpICsKICBnZW9tX2JveHBsb3QoYWVzKHkgPSBwcmVkKSwgYWxwaGEgPSAwLjIsIGNvbG9yID0gImdyZXkiKSArCiAgIyBnZW9tX3BvaW50KGFlcyh5ID0gcHJlZCksIGNvbG9yID0gInJlZCIsIGFscGhhID0gMC41KSArCiAgZ2VvbV9wb2ludChhZXMoeSA9IElWUyAtIG1lYW4oSVZTKSksIGFscGhhID0gMC41KSArCiAgIyBnZW9tX2JveHBsb3QoYWVzKHkgPSBJVlMgLSBtZWFuKElWUykpLCBhbHBoYSA9IDAuMiwgY29sb3IgPSAiZ3JleSIpICsKICBsYWJzKHRpdGxlID0gIm1vbmF0bGljaGUgSW52ZXJrZWhyc3NldHp1bmdlbiB2b24gUGVyc29uZW5rcmFmdHdhZ2VuIiwKICAgICAgIHN1YnRpdGxlID0gIlNjaHdlaXosIDIwMTMgLSAyMDE4IikKCgpgYGAKCiMjIyBBbHRlcm5hdGl2ZSBNb2RlbGxpZXJ1bmcgw7xiZXIgUXVhcnRhbGU/CgpEaWUgTW9kZWxsaWVydW5nIGRlciBlaW56ZWxuZW4gTW9uYXRlIGltIE1vZGVsbCBpbXBsaXppZXJ0IG5lYmVuIGRlbSBEYXR1bSB3ZWl0ZXJlIDExIER1bW15dmFyaWFibGVuLiBFcyBzdGVsbHQgc2ljaCBkaWUgRnJhZ2UsIG9iIGVzIG5pY2h0IGVpbiBlaW5mYWNoZXJlcyBNb2RlbGwgZ2lidC4gRWluIEFuc2F0enB1bmt0IHfDpHJlIHN0YXR0IE1vbmF0ZW4gRHVtbXl2YXJpYWJsZW4gZsO8ciBRdWFydGFsZSB6dSB2ZXJ3ZW5kZW4uIAoKYGBge3J9CgojIERlciBlaW5mYWNoIERhdGFmcmFtZSBpdnNfc2ltcGxlIG1pdCBkZW4gU3BhbHRlbiBJVlMgdW5kIERhdHVtCiMgd2lyIGhpZXIgZXJ3ZWl0ZXJ0OiBkaWUgTnVtbWVyIGRlcyBNb25hdHMgd2lyZCBhbHMgendlaXN0ZWxsaWdlIFplaWNoZW5rZXR0ZSBlcmfDpG56dC4KaXZzX3NpbXBsZSA8LSBpdnNfc2ltcGxlICU+JSAKICBtdXRhdGUoUXVhcnRhbCA9IHF1YXJ0ZXIoRGF0dW0pKQoKIyBBdWZ0ZWlsZW4gZGVyIERhdGVuIGluIGVpbiBUcmFpbmluZ3MtIHVuZCBlaW4gVGVzdHNldAppdnNfc2ltcGxlX3RyYWluIDwtIGl2c19zaW1wbGUgJT4lIGZpbHRlcihEYXR1bSA8IGRhdGUoIjIwMTgtMDEtMDEiKSkKaXZzX3NpbXBsZV90ZXN0IDwtIGl2c19zaW1wbGUgJT4lIGZpbHRlcihEYXR1bSA+PSBkYXRlKCIyMDE4LTAxLTAxIikpCgojIEVybmV1dGUgQmVyZWNobnVuZyBkZXMgTW9kZWxscyAuLi4KbW9kIDwtIGxtKGZvcm11bGEgPSBJVlMgfiBEYXR1bSArIFF1YXJ0YWwsIGRhdGEgPSBpdnNfc2ltcGxlX3RyYWluKQoKIyAuLi4gdW5kIEF1c2dhYmUgZGVyIE1vZGVsbGVyZ2Vibmlzc2UKc3VtbWFyeShtb2QpCgpgYGAKCkRlciBFcmtsw6RydW5nc2dlaGFsdCBpc3QgamVkb2NoIHZlcm5hY2hsw6Rzc2lnYmFyLCBkYXMgU2Fpc29udmVyaGFsdGVuIGRlciBJVlMgaXN0IG5pY2h0IMO8YmVyIFF1YXJ0YWxlIGFiYmlsZGJhciwgbnVyIDMgJSBkZXIgVmFyaWFueiB3ZXJkZW4gw7xiZXIgZWluIFF1YXJ0YWxtb2RlbGwgZXJrbMOkcnQsIGRhcyBNb2RlbGwgaXN0IHp1ZGVtIG5pY2h0IHN0YXRpc3RzaWNoIHNpZ25pZmlrYW50LgoKIyMjIFRlc3QgZWluZXIgYWx0ZXJuYXRpdmUgTW9kZWxsaWVydW5nIGFscyBBUklNQQoKRWluIEFsdGVybmF0aXZlIGvDtm5udGUgZGllIEJldHJhY2h0dW5nIGRlcyBVbXPDpHR6ZSBhbHMgQVJJTUEtUHJvemVzcyBzZWluLiBBUklNQSBzdGVodCBmw7xyIEF1dG9yZWdyZXNzaXZlIEludGVyZ3JpZXJ0ZSBNb3ZpbmcgQXZlcmFnZSAtIFByb3plc3NlLiBEYWJlaSBoYW5kZWx0IGVzIHNpY2ggdW0genVzYW1tZW5nZXNldHp0ZSBQcm96ZXNzbW9kZWxsZS4gZGVyIGF1dG9yZWdyZXNzaXZlIFRlaWwgYmV6aWVodCBuaW1tdCBCZXp1ZyBhdWYgZGllIFJlYWxpc2lhdGlvbmVuIGRlciBWb3JwZXJpb2Rlbi4gRGVyIE1vdmluZy1BdmVyYWdlLVRlaWwgYmlsZGVuIGRlbiBnZXdvZ2VuZW4gRHVyY2hzY2huaXR0IGRlciBGZWhsZXIgZGVyIHZlcmdhbmdlbmVuIFBlcmlvZGVuLiBTaW5kIGRpZSBQcm96ZXNzZSB6dWRlbSBuaWNodCBzdGF0aW9uw6RyICh4eHgpLCB3ZXJkZW4gZGllc2UgenVuw6RjaHN0IGVpbi0gb2RlciBtZWhybWFscyBkaWZmZXJlbnppZXJ0LCB3b2R1cmNoIFN0YXRpb25hcml0w6R0IGVycmVpY2hiYXIgaXN0LiBEdXJjaCBJbnRlZ3JhdGlvbiBkZXIgU3RhdGlvbsOkcmVuIFByb3plc3NlIGthbm4gbWFuIHdpZWRlciBhdWYgZGVuIHVyc3Byw7xuZ2xpY2hlbiBQcm96ZXNzIHp1csO8Y2tzY2hsaWXDn2VuLgoKVW13YW5kbHVuZyBkZXIgRGF0ZW4gaW4gZWluZSBaZWl0cmVpaGUgKEtsYXNzZSB0cykgdW5kIERhcnN0ZWxsdW5nIHZvbiBMaW5pZW5wbG90LCBBQ0YgdW5kIFBBQ0YgKEF1dG9jb3JyZWxhdGlvbmZ1bmN0aW9uIHVuZCBwYXJ0aWFsIEFDRikuCgpgYGB7cn0KIyBVbXdhbmRsdW5nIGRlciBEYXRlbiBpbiBkZW4gRGF0ZW50eXAgVGltZVNlcmllcyAidHMiCml2c190c190cmFpbiA8LSB0cyhpdnNfc2ltcGxlX3RyYWluJElWUywgc3RhcnQgPSBjKDIwMTMsMSksIGZyZXF1ZW5jeSA9IDEyKQppdnNfdHNfdGVzdCA8LSB0cyhpdnNfc2ltcGxlX3Rlc3QkSVZTLCBzdGFydCA9IGMoMjAxOCwxKSwgZnJlcXVlbmN5ID0gMTIpCgppdnNfdHNfdHJhaW4gJT4lIGdndHNkaXNwbGF5KGxhZy5tYXggPSA2MCkKYGBgCgpEaWUgUmVpaGUgaXN0IG5pY2h0IHN0YXRpb27DpHIuIEVyc3QgZGllIHp3ZWlmYWNoZSBEaWZmZXJlbnppZXJ1bmcgYnJpbmd0IGVpbiBFcmdlYm5pczoKCmBgYHtyfQppdnNfdHNfdHJhaW4gJT4lIAogIGRpZmYoKSAlPiUgCiAgZ2d0c2Rpc3BsYXkobGFnLm1heCA9IDYwLCBtYWluID0gIml2c19zaW1wbGVfdHJhaW4kSVZTLCBkaWZmZXJlbnRpYXRlZCIpCgpgYGAKCgpgYGB7cn0KaXZzX3RzX3RyYWluICU+JSAKICBkaWZmKCkgJT4lIAogIGRpZmYobGFnID0gMTIpICU+JSAKICBnZ3RzZGlzcGxheShsYWcubWF4ID0gNjAsIG1haW4gPSAiSVZTIDIwMTMgLSAyMDE4LCB6d2VpZmFjaCBkaWZmZXJlbnppZXJ0IikKYGBgCgpgYGB7cn0KZml0IDwtIEFyaW1hKGl2c190c190cmFpbiwgb3JkZXIgPSBjKDIsMSwwKSwgc2Vhc29uYWwgPSBjKDAsMSwxKSkKY2hlY2tyZXNpZHVhbHMoZml0KQoKIyByZXNpZHVhbHMgbG9vayBsaWtlIHduIC0+IG9rCiMgYWNmIHdpdGhpbiBib3VuZHJpZXMgLT4gbm8gY29ycmVsYXRpb24gaW4gZml0dGV0IHNlcmllcywgcmVzIGluZGVwZW5kZW50bHkgZGlzdHJpYnV0ZWQKIyBxcSBwbG90IG5vdCBwZXJmZWN0IC0+IGNvbmZpZGVuY2UgaW50ZXJ2YWxscyBtYXkgYmUgbWlzbGVhZGluZwojIGxqdW5nLWJveDogY291bGQgYmUgYmV0dGVyLCBidXQgd2UgaGF2ZSBubyBiZXR0ZXIgbW9kZWwgc28gZmFyIAojIEFjZihmaXQkcmVzaWR1YWxzLCBsYWcgPSA2MCkKIyBCb3gudGVzdChmaXQkcmVzaWR1YWxzLCBsYWcgPSAxMiwgdHlwZSA9ICJMaiIsIGZpdGRmID0gMykKCmZjIDwtIGZvcmVjYXN0KGZpdCwgaCA9IDEyKQoKYXV0b3Bsb3QoZmMpCmZQZXJmb3JtYW5jZShkYXRhLmZyYW1lKElWUyA9IGl2c190c190ZXN0LCBwcmVkID0gZmMkbWVhbikpCgpgYGAKSW0gRXJnZWJuaXMgZXJoYWx0ZW4gd2lyIGVpbiBlcmhlYmxpY2ggYmVzc2VyZXMgTW9kZWxsLiBybXNlIGdlc3Vua2VuIHZvbiAyLjUyMiBhdWYgMTg5MC4KCiMjIyBEaWZmZXJlbnppZXJ1bmcgZGVyIEFudHJpZWJzYXJ0CgpEaWUgV2llZGVyaG9sdW5nIGRlciBBbmFseXNlIG1pdCBkZW0genVzw6R0emxpY2hlbiBSZWdyZXNzb3IgemVpZ3QgZWluIHbDtmxsaWcgYW5kZXJlcyBCaWxkLgoKYGBge3IgbWVzc2FnZT1GQUxTRX0KCiMgRGF0ZW4gZGVzIFN0YXRpc3Rpc2NoZW4gQnVuZGVzYW10ZXMgbWl0IEluZm9ybWF0aW9uZW4genVyIFRyZWlic3RvZmZhcnQKaXZzX3Jhd19mdWVsIDwtCiAgcmVhZF9jc3YoZmlsZSA9ICJEYXRlbi8yMDE5MDgyNCBOZXV6dWxhc3N1bmdlbiBDSCBUcmVpYnN0b2ZmLmNzdiIsCiAgICAgICAgICAgc2tpcCA9IDIsCiAgICAgICAgICAgbG9jYWxlID0gbG9jYWxlKGVuY29kaW5nID0gImxhdGluMSIpKSAjIFdpbmRvd3MgTGF0aW4gMQoKIyBEYXRlbiB2b3JiZXJlaXRlbgppdnNfZnVlbCA8LSBpdnNfcmF3X2Z1ZWwgJT4lCiAgc2VsZWN0KC0iRmFocnpldWdncnVwcGUgLyAtYXJ0IikgJT4lICMgRXMgd3VyZGUgbnVyIFBlcnNvbmVua3JhZnR3YWdlbiBhdXNnZXfDpGhsdCwgU3BhbHRlIEZhaHJ6ZXVncnVwcGUgbMO2c2NoZW4KICBnYXRoZXIoa2V5ID0gSmFociwgdmFsdWUgPSAiSVZTIiwgLU1vbmF0LCAtVHJlaWJzdG9mZikgJT4lICMgZGllIEphaHJlc3NwYWx0ZW4gaW4gWmVpbGVuIHVtYmF1ZW4KICBtdXRhdGUoRGF0dW0gPSBtb250aHNFbmQoSmFociwgTW9uYXQpKSAlPiUgICMgSmFociBNb25hdCB1bWJhdWVuIGF1ZiBlaW5lIERhdHVtIHp1bSBNb25hdHNlbmRlCiAgbXV0YXRlKE1vbmF0ID0gc3RyX3BhZChtb250aChEYXR1bSksIDIsIHBhZCA9ICIwIikpICU+JSAKICBmaWx0ZXIoRGF0dW0gPiB5bWQoIjIwMTItMTItMzEiKSkgJT4lIAogIHNlbGVjdChEYXR1bSwgTW9uYXQsIFRyZWlic3RvZmYsIElWUykKCiMgR3JhcGhpc2NoZSBEYXJzdGVsbHVuZywgZGlmZmVyZW56aWVydCBuYWNoIFRyZWlic3RvZmZhcnQsIGVyemV1Z2VuIGFiZXIgbm9jaCBuaWNodCBhbnplaWdlbgpwIDwtIGl2c19mdWVsICU+JQogIGdncGxvdChhZXMoeCA9IERhdHVtLCBjb2xvciA9IFRyZWlic3RvZmYsLCBsaW5ldHlwZSA9IFRyZWlic3RvZmYpKSArCiAgbGFicyh0aXRsZSA9ICJJbnZlcmtlaHJzc2V0enVuZ2VuIFBLVywgbmFjaCBUcmVpYnN0b2ZmYXJ0IiwKICAgICAgIHN1YnRpdGxlID0gIlNjaHdlaXosIDIwMTMgLSAyMDE4IikgICsKICBzY2FsZV94X2RhdGUoCiAgICBuYW1lID0gIiIsCiAgICBsaW1pdHMgPSBjKHltZCgiMjAxMy0wMS0wMSIsICIyMDE4LTEyLTMxIikpLAogICAgZGF0ZV9sYWJlbHMgPSAiJW0vJXkiLAogICAgZGF0ZV9taW5vcl9icmVha3MgPSAiMiBtb250aHMiLAogICAgZGF0ZV9icmVha3MgPSAieWVhcnMiCiAgKQoKIyBMaW5lYXJlIFNrYWxhCnAgKyBzY2FsZV95X2NvbnRpbnVvdXMobmFtZSA9ICJJbnZlcmtlaHJzc2V0enVuZ2VuIHBybyBNb25hdCIsIGxhYmVscyA9IGZvcm1hdFQpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBJVlMpKQoKIyBMb2dhcml0aG1pc2NoZSBTa2FsYQpwICsgc2NhbGVfeV9sb2cxMChuYW1lID0gIkludmVya2VocnNzZXR6dW5nZW4gcHJvIE1vbmF0IiwgbGFiZWxzID0gZm9ybWF0VCkgKwogIGdlb21fbGluZShhZXMoeSA9IElWUyksIAogICAgICAgICAgICBkYXRhID0gaXZzX2Z1ZWxbaXZzX2Z1ZWwkSVZTID4gMCxdKQoKYGBgCkRpZSBUcmVpYnN0b2ZmYXJ0ZW4gIkFuZGVyZXIiIHVuZCAiT2huZSBNb3RvciIgc3BpZWxlbiBpbiBkZXIgQW5hbHlzZSBrZWluZSBiZXNvbmRlcmUgUm9sbGUuIFp1ciBiZXNzZXJlbiDDnGJlcnNpY2h0bGljaGtlaXQgd2VyZGVuIHNpZSBhdXNnZXNjaGxvc3Nlbi4KCmBgYHtyfQoKIyBBdXNzY2hsdXNzIHZvbiBHYXMgdW5kIFRyZWlic3RvZmZhcnRlbiAiQW5kZXJlciIgc293aWUgb2huZSBNb3RvcgppdnNfZnVlbCA8LSBpdnNfZnVlbCAlPiUgCiAgIyBmaWx0ZXIoIVRyZWlic3RvZmYgJWluJSBjKCJBbmRlcmVyIiwgIkdhcyAobW9uby0gdW5kIGJpdmFsZW50KSIsICJPaG5lIE1vdG9yIikpCiAgZmlsdGVyKCFUcmVpYnN0b2ZmICVpbiUgYygiQW5kZXJlciIsICJPaG5lIE1vdG9yIikpCgojIExpbmVhcmUgU2thbGEKcCArIHNjYWxlX3lfY29udGludW91cyhuYW1lID0gIkludmVya2VocnNzZXR6dW5nZW4gcHJvIE1vbmF0IiwgbGFiZWxzID0gZm9ybWF0VCkgKwogIGdlb21fbGluZShhZXMoeSA9IElWUywgbGluZXR5cGUgPSBUcmVpYnN0b2ZmKSwgZGF0YSA9IGl2c19mdWVsKQoKIyBMb2dhcml0aG1pc2NoZSBTa2FsYQpwICsgc2NhbGVfeV9sb2cxMChuYW1lID0gIkludmVya2VocnNzZXR6dW5nZW4gcHJvIE1vbmF0IiwgbGFiZWxzID0gZm9ybWF0VCkgKwogIGdlb21fbGluZShhZXMoeSA9IElWUywgbGluZXR5cGUgPSBUcmVpYnN0b2ZmKSwgCiAgICAgICAgICAgIGRhdGEgPSBpdnNfZnVlbFtpdnNfZnVlbCRJVlMgPiAwLF0pCgpgYGAKCiMjIyBMaW5lYXJlIE1vZGVsbGUgamUgVHJlaWJzdG9mZmFydAoKIyMjIyBNb2RlbGxlIGJlcmVjaG5lbiB1bmQgcGxvdHRlbgoKYGBge3J9CiMgRGF0ZW4gaW4gVHJhaW5pbmcgdW5kIFRlc3QgYXVmc3BsaXR0ZW4KaXZzX3RyYWluIDwtIGl2c19mdWVsICU+JSBmaWx0ZXIoRGF0dW0gPCBkYXRlKCIyMDE4LTAxLTAxIikpCml2c190ZXN0IDwtIGl2c19mdWVsICU+JSBmaWx0ZXIoRGF0dW0gPj0gZGF0ZSgiMjAxOC0wMS0wMSIpKQoKIyBkYXMgbGluZWFyZSBNb2RlbGwgaW4gZWluZXIgRnVua3Rpb24ga2Fwc2VsbgpmTW9kIDwtIGZ1bmN0aW9uKGRmKXsKICBsbShJVlMgfiBEYXR1bSArIE1vbmF0LCBkYXRhID0gZGYpCn0KCiMgamUgVHJlaWJzdG9mZmFydCBkaWUgVHJhaW5pbmdzZGF0ZW4gZ3J1cHBpZXJlbiB1bmQgaW4gZWluZW4gVW50ZXJkYXRhZnJhbWUgc2FtbW1lbG4KaXZzX21vZGVscyA8LSBpdnNfdHJhaW4gJT4lIAogIGdyb3VwX2J5KFRyZWlic3RvZmYpICU+JQogIG5lc3QoKSAlPiUgIyBlaW4gRGF0ZW5zYXR6IGplIFRyZWlic3RvZmZhcnQgbWl0IFVudGVyZGF0YWZyYW1lCiAgbXV0YXRlKCAjIGbDvHIgamVkZSBUcmVpYnN0b2ZmYXJ0IC4uLgogICAgbW9kZWwgPSBtYXAoZGF0YSwgZk1vZCksICMgLi4uIGJlcmVjaG5lIGVpbiBsaW5lYXJlcyBNb2RlbGwKICAgIGRhdGEgPSBtYXAyKGRhdGEsIG1vZGVsLCBhZGRfcmVzaWR1YWxzKSwgIyAuLi4gUmVzaWR1ZW4gaGluenVmw7xnZW4KICAgIGRhdGEgPSBtYXAyKGRhdGEsIG1vZGVsLCBhZGRfcHJlZGljdGlvbnMpLCAjIC4uLiB1bmQgZ2VzY2jDpHR6dGUgV2VydGUKICAgIGdsYW5jZSA9IG1hcChtb2RlbCwgYnJvb206OmdsYW5jZSkgIyBLZW5uenVhaGxlbiB6dSBNb2RlbGxwZXJmb3JtYW5jZSBiZXJlY2huZW4KICkKCiMgRGllIFVudGVyZGF0YWZyYW1lcyB3aWVkZXIgYXVmbMO2c2VuIC4uLgppdnNfdHJhaW4gPC0gaXZzX21vZGVscyAlPiUgdW5uZXN0KGNvbHMgPSBjKGRhdGEpKQoKIyAuLi4gdW5kIE1vZGVsbG1ldHJpa2VuIGluIGVpbmVtIGVpZ2VuZW4gZGYgc3BlaWNoZXJuLgppdnNfbWV0cmljcyA8LSBpdnNfbW9kZWxzICU+JSAKICB1bm5lc3QoY29scyA9IGMoZ2xhbmNlKSkgJT4lIAogIHNlbGVjdCgtZGF0YSwgLW1vZGVsKSAKCiMgUGxvdHMKaXZzX3RyYWluW2l2c190cmFpbiRJVlMgPiAwICYgaXZzX3RyYWluJHByZWQgPiAwLF0gJT4lIAogIGdncGxvdChhZXMoeCA9IERhdHVtKSkgKyAjIERhdHVtIGF1ZiBkZXIgeC1BY2hzZWwKICBnZW9tX2xpbmUoYWVzKHkgPSBJVlMpLCBjb2xvciA9ICJibGFjayIpICsgIyB0YXRzw6RjaGxpY2hlIFdlcnRlIHVuZCAuLi4uCiAgZ2VvbV9saW5lKGFlcyh5ID0gcHJlZCksIGNvbG9yID0gImJsdWUiLCBsaW5ldHlwZSA9IDIpICsgIyBQcmVkaWt0b3JlbiBhdWYgZGVyIHktQWNoc2UKICBzY2FsZV95X2xvZzEwKCkgKyAjIExvZ2FyaXRobWlzY2hlIE9yZGluYXRlCiAgZmFjZXRfd3JhcCggfiBUcmVpYnN0b2ZmKSAjIGtsZWluZSBTdWJkaWFncmFtbSBqZSBUcmVpYnN0b2ZmYXJ0LgoKIyBNb2RlbGxtZXRyaWtlbiBhdXNnZWJlbgppdnNfbWV0cmljcyAlPiUgYXJyYW5nZShyLnNxdWFyZWQpIAoKYGBgCgojIyMjIFBlcmZvcm1hbmNlYmVyZWNobnVuZwoKSmUgVHJlaWJzdG9mZmFydCB3ZXJkZW4gZsO8ciBkYXMgamV3ZWlsZ2UgTW9kZWxsIGRpZSBNb2RlbGxrZW5uemFobGVuIGVybWl0dGVsdC4KCmBgYHtyfQojIE1vZGVsbHBlcmZvcm1hbmNlIGJlcmVjaG5lbgoKaXZzX3Rlc3QgPC0gaXZzX3Rlc3QgJT4lCiAgZ3JvdXBfYnkoVHJlaWJzdG9mZikgJT4lIAogIG5lc3QoKSAlPiUgIyAibmVzdCIgamUgVHJlaWJzdG9mZmFydAogIGFkZF9jb2x1bW4obW9kZWwgPSBpdnNfbW9kZWxzJG1vZGVsKSAlPiUgIyBiZXJlaXRzIGJlcmVjaG5ldGVzIE1vZGVsbCBoaW56dWbDvGdlbgogIG11dGF0ZSgKICAgIGRhdGEgPSBtYXAyKGRhdGEsIG1vZGVsLCBhZGRfcmVzaWR1YWxzKSwgIyBSZXNpZHVlbiBlcmfDpG56ZW4gLi4uCiAgICBkYXRhID0gbWFwMihkYXRhLCBtb2RlbCwgYWRkX3ByZWRpY3Rpb25zKSwgIyBWb3JoZXJzYWdld2VydGUgZGF6dWdlYmVuCiAgICBwZm1jID0gbWFwKGRhdGEsIGZQZXJmb3JtYW5jZSkpICU+JSAjIE1vZGVsbGtlbm56YWhsIGJlcmVjaG5lbi4KICBzZWxlY3QoLW1vZGVsKSAjIGRpZSBTcGFsdGUgbW9kZWwgd2lyZCBuaWNodCBtZWhyIGJlbsO2dGlndAoKaXZzX3Rlc3RfbWV0cmljcyA8LSBpdnNfdGVzdCAlPiUgIyBjcmVhdGUgZGF0YWZyYW1lIHdpdGggbW9kZWwgbWV0cmljcwogIHNlbGVjdCgtZGF0YSkgJT4lIAogIHVubmVzdChwZm1jKQoKaXZzX3Rlc3QgPC0gaXZzX3Rlc3QgJT4lICMgZXJzdGVsbGUgZWluZW4gRGF0YWZyYW1lIG1pdCBQcm9nbm9zZW4gdW5kIFJlc2lkdWVuCiAgc2VsZWN0KC1wZm1jKSAlPiUgCiAgdW5uZXN0KGRhdGEpCgppdnNfdGVzdFtpdnNfdGVzdCRJVlMgPiAwICYgaXZzX3Rlc3QkcHJlZCA+IDAsXSAlPiUgIyBiaXR0ZSBrZWluZSBOdWxsZW4sIGRpZSBsb2dhcml0aG1pZXJ0IHdlcmRlbiAuLi4KICBnZ3Bsb3QoYWVzKHggPSBEYXR1bSkpICsKICBnZW9tX2xpbmUoYWVzKHkgPSBJVlMpLCBjb2xvciA9ICJibGFjayIpICsgIyB0YXRzw6RjaGxpY2hlIFdlcnRlCiAgZ2VvbV9saW5lKGFlcyh5ID0gcHJlZCksIGNvbG9yID0gInJlZCIsIGxpbmV0eXBlID0gMikgKyAjIFZvcmhlcnNhZ2V3ZXJ0ZQogIHNjYWxlX3lfbG9nMTAoKSArICMgbG9nYXJpdGhtaXNjaGUgU2thbGEKICBmYWNldF93cmFwKH4gVHJlaWJzdG9mZikgIyBVbnRlcmRpYWdyYW1tIGplIFRyZWlic3RvZmZhcnQKCml2c190ZXN0X21ldHJpY3MgJT4lIGFycmFuZ2UobWFwZSkgCgpgYGAKCiMjIyBBUklNQS1Nb2RlbGxlIGplIFRyZWlic3RvZmZhcnQKCiMjIyMgTW9kZWxsZSBiZXJlY2huZW4gdW5kIHBsb3R0ZW4KCmBgYHtyfQojIERhdGVuIGluIFRyYWluaW5nIHVuZCBUZXN0IGF1ZnNwbGl0dGVuCml2c190cmFpbiA8LSBpdnNfZnVlbCAlPiUgZmlsdGVyKERhdHVtIDwgZGF0ZSgiMjAxOC0wMS0wMSIpKSAlPiUgc2VsZWN0KC1Nb25hdCkKaXZzX3Rlc3QgPC0gaXZzX2Z1ZWwgJT4lIGZpbHRlcihEYXR1bSA+PSBkYXRlKCIyMDE4LTAxLTAxIikpICU+JSBzZWxlY3QoLU1vbmF0KSAKCiMgamUgVHJlaWJzdG9mZmFydCBkaWUgVHJhaW5pbmdzZGF0ZW4gZ3J1cHBpZXJlbiB1bmQgaW4gZWluZW4gVW50ZXJkYXRhZnJhbWUgc2FtbW1lbG4KaXZzX21vZGVscyA8LSBpdnNfdHJhaW4gJT4lIAogIGdyb3VwX2J5KFRyZWlic3RvZmYpICU+JQogIG5lc3QoKSAlPiUgIyBlaW4gRGF0ZW5zYXR6IGplIFRyZWlic3RvZmZhcnQgbWl0IFVudGVyZGF0YWZyYW1lCiAgbXV0YXRlKCAjIGbDvHIgamVkZSBUcmVpYnN0b2ZmYXJ0IC4uLgogICAgdHMgPSBtYXAoZGF0YSwgfiB0cygueCRJVlMsIHN0YXJ0ID0gYygyMDEzLDEpLCBmcmVxdWVuY3kgPSAxMikpLCAjIFplaXRyZWloZSBqZSBUcmVpYnN0b2ZmYXJ0CiAgICBtb2RlbCA9IG1hcCh0cywgfiBhdXRvLmFyaW1hKC54KSksICMgLi4uIGJlcmVjaG5lIGVpbiBBUklNQS1Nb2RlbGwKICAgIGZjID0gbWFwKG1vZGVsLCB+IGZvcmVjYXN0KC54LCBoID0gMTIpKQogKQoKbWFwMihpdnNfbW9kZWxzJGZjLCAKICAgICBpdnNfbW9kZWxzJFRyZWlic3RvZmYsIH4gYXV0b3Bsb3QoLngsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB4bGFiID0gTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWxhYiA9ICJBbnphaGwgSW52ZXJrZWhyc3NldHp1bmdlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1haW4gPSBwYXN0ZSgiSVZTIGluIGRlciBUcmVpYnN0b2ZmYXJ0IiwgLnkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkgKyAKICAgICAgIGxhYnMoY2FwdGlvbiA9IC54JG1ldGhvZCwgdGl0bGUgPSBwYXN0ZSgiSVZTIGluIGRlciBUcmVpYnN0b2ZmYXJ0IiwgLnkpKSArIAogICAgICAgZ2VvbV9saW5lKGRhdGEgPSBpdnNfdGVzdCwgYWVzKHggPSBEYXR1bSwgeSA9IElWUykpCiAgICAgKQoKYGBgCgojIyMjIFBlcmZvcm1hbmNlYmVyZWNobnVuZwoKSmUgVHJlaWJzdG9mZmFydCB3ZXJkZW4gZsO8ciBkYXMgamV3ZWlsZ2UgTW9kZWxsIGRpZSBNb2RlbGxrZW5uemFobGVuIGVybWl0dGVsdC4KCmBgYHtyfQojIE1vZGVsbHBlcmZvcm1hbmNlIGJlcmVjaG5lbgoKaXZzX3Rlc3RfbWV0cmljcyA8LSBpdnNfdGVzdCAlPiUKICBncm91cF9ieShUcmVpYnN0b2ZmKSAlPiUgCiAgbmVzdCgpICU+JSAjICJuZXN0IiBqZSBUcmVpYnN0b2ZmYXJ0CiAgYWRkX2NvbHVtbihtb2RlbCA9IGl2c19tb2RlbHMkZmMpICU+JSAjIGVudGjDpGx0IGF1Y2ggZGllIFByb2dub3Nld2VydGUKICBtdXRhdGUoZGF0YSA9IG1hcDIoZGF0YSwgbW9kZWwsIH4gYWRkX2NvbHVtbigueCwgcHJlZCA9IC55JG1lYW4pKSwKICAgICAgICAgcGZtYyA9IG1hcChkYXRhLCBmUGVyZm9ybWFuY2UpKSAjIFBlcmZvcm1hbmNlIGJlcmVjaG5lbi4KICAKaXZzX3Rlc3RfbWV0cmljcyA8LSBpdnNfdGVzdF9tZXRyaWNzICU+JSAjIHVubmVzdCBtb2RlbCBtZXRyaWNzCiAgIyBzZWxlY3QoLSBjKGRhdGEsIG1vZGVsKSkgJT4lIAogIHVubmVzdChwZm1jKQoKaXZzX3Rlc3RfbWV0cmljcyAlPiUgYXJyYW5nZShtYXBlKSAKCmBgYAoKIyMjIFF1ZWxsZW4KCkJhY2toYXVzIGV0IGFsLiAoMjAxOCk6IE11bHRpdmFyaWF0ZSBBbmFseXNlbWV0aG9kZW4uIEVpbmUgYW53ZW5kdW5nc29yaWVudGllcnRlIEVpbmbDvGhydW5nLiAxNSBBdWZsLiBCZXJsaW4uIEhlaWRlbGJlcmcuIFtTcHJpbmdlci1WZXJsYWddKGh0dHBzOi8vd3d3LnNwcmluZ2VyLmNvbS9kZS9ib29rLzk3ODM2NjI1NjY1NDEpLgoKSWxnLCBNYXJrdXM7IEJhdW1laXN0ZXIsIEFsZXhhbmRlciAoMjAxOSk6IEFuYWx5dGljcyBpbSBNYXJrZXRpbmctQ29udHJvbGxpbmcuIEluOiBEaWUgRGlnaXRhbGlzaWVydW5nIGRlcyBDb250cm9sbGluZ3M6IEFud2VuZHVuZ3NiZWlzcGllbGUgYXVzIFRoZW9yaWUgdW5kIFByYXhpcywgaHJzZy4gdm9uIElta2UgS2VpbWVyIHVuZCBVbHJpY2ggRWdsZS4gU3ByaW5nZXIuCgpSdXBwZXJ0LCBEYXZpZDsgTWF0dGVzb24sIERhdmlkIFMuICgyMDE1KTogU3RhdGlzdGljcyBhbmQgRGF0YSBBbmFseXNpcyBmb3IgRmluYW5jaWFsIEVuZ2luZWVyaW5nIFtTcHJpbmdlci1WZXJsYWddKGh0dHBzOi8vd3d3LnNwcmluZ2VyLmNvbS9kZS9ib29rLzk3ODE0OTM5MjYxMzgp